package com.pand.task;

import com.pand.model.order.OrderItem;
import com.pand.model.vehicle.RentVehicle;
import com.pand.mysql.model.Order;
import com.pand.mysql.service.OrderService;
import com.pand.mysql.service.StationService;
import com.pand.service.VehicleService;
import com.pand.util.PriceCaculatorUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * Created by lh on 2017/11/8.
 */
public class OrderTask {
    private static final Logger LOGGER = LoggerFactory.getLogger(OrderTask.class);

    @Autowired
    @Qualifier("orderService")
    OrderService orderService;

    @Autowired
    @Qualifier("originalOrderService")
    com.pand.service.OrderService originalOrderService;

    @Autowired
    VehicleService vehicleService;

    @Autowired
    StationService stationService;

    private static final long MILLISECONDS = 5 * 1000;
    private static final int SECONDS = 2 * 60;

    private static List<Order> orders = new ArrayList<>();
    private static List<Order> pushedOrders = new ArrayList<>();

    private static Date beforeTime;
    private static Date nowTime;

    @Value("${is.test.push}")
    private boolean isTestPush = false;

    @Scheduled(cron = "0/20 * * * * ?")
    public void pushOrder() {
        if (isTestPush) {
            getTestOrders().stream().limit(10).forEach(order -> {
                OrderPushThread.ORDERS.add(order);
                pushedOrders.add(order);
            });
        } else {
            getOrders().stream().forEach(order -> {
                OrderPushThread.ORDERS.add(order);
            });
        }
    }

    private List<Order> getOrders() {
        if (nowTime == null) {
            Date now = new Date();
            now.setTime(now.getTime() - 20 * 1000);
            beforeTime = now;
            nowTime = new Date();
        } else {
            Date before = new Date();
            before.setTime(nowTime.getTime());
            beforeTime = before;
            nowTime = new Date();
        }
        List<Order> orderList = originalOrderService.findOrdersByTime(beforeTime, nowTime).parallelStream()
                .map(originalOrder -> {
                    Order order = new Order();
                    order.setCustomerName(originalOrder.getContactorName());
                    order.setPhone(originalOrder.getContactorPhone());
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    if (originalOrder.getCreateTime() != null) {
                        order.setCreateTime(dateFormat.format(originalOrder.getCreateTime()));
                    }
                    OrderItem item = originalOrderService.findOrderItemByOrderNo(originalOrder.getOrderNo());
                    if (item != null) {
                        RentVehicle vehicle = vehicleService.findByVehicleId(item.getVehicleId());
                        order.setVin(vehicle.getVinCode());
                        order.setLicense(item.getLicense());
                        if (item.getRealGetTime() != null) {
                            order.setGetTime(dateFormat.format(item.getRealGetTime()));
                        }
                        if (item.getRealRetTime() != null) {
                            order.setRetTime(dateFormat.format(item.getRealRetTime()));
                        }
                        if (item.getGetStationId() != null) {
                            order.setGetStation(stationService.findOne(item.getGetStationId()));
                        }
                        if (item.getRetStationId() != null) {
                            order.setRetStation(stationService.findOne(item.getRetStationId()));
                        }
                    }
                    if (originalOrder.getModTime() != null) {
                        order.setModTime(dateFormat.format(originalOrder.getModTime()));
                    }
                    if (originalOrder.getTradeTime() != null) {
                        order.setCompleteTime(dateFormat.format(originalOrder.getTradeTime()));
                    }
                    if (originalOrder.getOrderStatus().equals(Order.StatusType.RETURNED.getCode())
                            || originalOrder.getOrderStatus().equals(Order.StatusType.COMPLETED.getCode())) {
                        order.setTimeLength((item.getRealRetTime().getTime() - item.getRealGetTime().getTime()) / 1000);
                    }
                    order.setStatus(originalOrder.getOrderStatus());
                    if (order.getStatus() != null && order.getStatus().equals(Order.StatusType.COMPLETED.getCode())) {
                        DecimalFormat decimalFormat = new DecimalFormat("0.00");
                        order.setPrice(decimalFormat.format(originalOrder.getTimeAmount()));
                    }
                    return order;
                }).collect(Collectors.toList());

        if (orderList.size() > 0) {
            orderService.save(orderList);
        }
        return orderList;
    }


    private List<Order> getTestOrders() {
        if (orders.isEmpty()) {
            LOGGER.info("-----订单数据重新轮询推送-----");
            List<Order> reservedOrders = orderService.findAll().parallelStream().filter(order -> order.getCreateTime() != null)
                    .map(order -> {
                        order.setStatus(Order.StatusType.RESERVED.getCode());
                        order.setStatusName(Order.StatusType.RESERVED.getValue());
                        order.setGetTime(null);
                        order.setRetTime(null);
                        order.setCompleteTime(null);
                        order.setPrice("");
                        return order;
                    })
                    .collect(Collectors.toList());

            List<Order> cancelOrders = orderService.findAll().parallelStream().filter(order -> order.getStatus().equals(Order.StatusType.CANCELLED.getCode())
                    || order.getStatus().equals(Order.StatusType.CLOSED.getCode()))
                    .map(order -> {
                        order.setStatus(Order.StatusType.RESERVED.getCode());
                        order.setStatusName(Order.StatusType.RESERVED.getValue());
                        order.setGetTime(null);
                        order.setRetTime(null);
                        order.setCompleteTime(null);
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        int randomSeconds = new Random().nextInt(10 * 60);
                        try {
                            Date modTime = new Date();
                            modTime.setTime(dateFormat.parse(order.getCreateTime()).getTime() + randomSeconds * 1000);
                            order.setModTime(dateFormat.format(modTime));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        order.setPrice("");
                        return order;
                    })
                    .collect(Collectors.toList());

            List<Order> usedOrders = orderService.findAll().parallelStream()
                    .filter(order -> order.getGetTime() != null
                            && (order.getStatus().equals(Order.StatusType.COMPLETED.getCode())
                            || order.getStatus().equals(Order.StatusType.USED.getCode())
                            || order.getStatus().equals(Order.StatusType.RETURNED.getCode())))
                    .map(order -> {
                        order.setStatus(Order.StatusType.USED.getCode());
                        order.setStatusName(Order.StatusType.USED.getValue());
                        order.setRetTime(null);
                        order.setCompleteTime(null);
                        order.setPrice("");
                        return order;
                    })
                    .collect(Collectors.toList());

            List<Order> returnedOrders = orderService.findAll().parallelStream()
                    .filter(order -> order.getRetTime() != null
                            && (order.getStatus().equals(Order.StatusType.COMPLETED.getCode())
                            || order.getStatus().equals(Order.StatusType.RETURNED.getCode())))
                    .map(order -> {
                        order.setStatus(Order.StatusType.RETURNED.getCode());
                        order.setStatusName(Order.StatusType.RETURNED.getValue());
                        order.setPrice("");
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        if (order.getGetTime() != null) {
                            try {
                                order.setTimeLength((dateFormat.parse(order.getRetTime()).getTime() - dateFormat.parse(order.getGetTime()).getTime()) / 1000);
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                        }
                        return order;
                    })
                    .collect(Collectors.toList());

            List<Order> completedOrders = orderService.findAll().parallelStream()
                    .filter(order -> order.getRetTime() != null
                            && order.getStatus().equals(Order.StatusType.COMPLETED.getCode()))
                    .map(order -> {
                        int randomSeconds = new Random().nextInt(SECONDS);
                        Date completeDate = new Date();
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        if (order.getRetTime() != null) {
                            try {
                                completeDate.setTime(dateFormat.parse(order.getRetTime()).getTime() + randomSeconds * 1000);
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                            order.setCompleteTime(dateFormat.format(completeDate));
                        }
                        order.setStatus(Order.StatusType.COMPLETED.getCode());
                        order.setStatusName(Order.StatusType.COMPLETED.getValue());
                        order.setPrice("");
                        if (order.getGetTime() != null && order.getRetTime() != null) {
                            try {
                                order.setPrice(PriceCaculatorUtil.getPrice(dateFormat.parse(order.getGetTime()), dateFormat.parse(order.getRetTime())));
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                        }
                        return order;
                    })
                    .collect(Collectors.toList());

            orders.addAll(reservedOrders);
            orders.addAll(usedOrders);
            orders.addAll(returnedOrders);
            orders.addAll(completedOrders);
        } else {
            if (pushedOrders.size() > 0) {
                orders.removeAll(pushedOrders);
                pushedOrders.clear();
            }
        }
        return orders;
    }

//    private List<Order> getOrders() {
//        if (orders.isEmpty()) {
//            LOGGER.info("-----订单数据重新轮询推送-----");
//            List<Order> reservedOrders = orderService.findAll().stream().filter(order -> order.getCreateTime() != null)
//                    .map(order -> {
//                        order.setStatus(Order.StatusType.RESERVED.getCode());
//                        order.setStatusName(Order.StatusType.RESERVED.getValue());
//                        order.setGetTime(null);
//                        order.setRetTime(null);
//                        order.setCompleteTime(null);
//                        return order;
//                    })
//                    .collect(Collectors.toList());
//
//            List<Order> usedOrders = orderService.findAll().stream()
//                    .filter(order -> order.getGetTime() != null
//                            && (order.getStatus().equals(Order.StatusType.COMPLETED.getCode())
//                            || order.getStatus().equals(Order.StatusType.USED.getCode())
//                            || order.getStatus().equals(Order.StatusType.RETURNED.getCode())))
//                    .map(order -> {
//                        order.setStatus(Order.StatusType.USED.getCode());
//                        order.setStatusName(Order.StatusType.USED.getValue());
//                        order.setRetTime(null);
//                        order.setCompleteTime(null);
//                        return order;
//                    })
//                    .collect(Collectors.toList());
//
//            List<Order> returnedOrders = orderService.findAll().stream()
//                    .filter(order -> order.getRetTime() != null
//                            && (order.getStatus().equals(Order.StatusType.COMPLETED.getCode())
//                            || order.getStatus().equals(Order.StatusType.RETURNED.getCode())))
//                    .map(order -> {
//                        order.setStatus(Order.StatusType.RETURNED.getCode());
//                        order.setStatusName(Order.StatusType.RETURNED.getValue());
//                        return order;
//                    })
//                    .collect(Collectors.toList());
//
//            List<Order> completedOrders = orderService.findAll().stream()
//                    .filter(order -> order.getRetTime() != null
//                            && order.getStatus().equals(Order.StatusType.COMPLETED.getCode()))
//                    .map(order -> {
//                        int randomSeconds = new Random().nextInt(SECONDS);
//                        Date completeDate = new Date();
//                        completeDate.setTime(order.getRetTime().getTime() + randomSeconds * 1000);
//                        order.setCompleteTime(completeDate);
//                        order.setStatus(Order.StatusType.COMPLETED.getCode());
//                        order.setStatusName(Order.StatusType.COMPLETED.getValue());
//                        return order;
//                    })
//                    .collect(Collectors.toList());
//
//            orders.addAll(reservedOrders);
//            orders.addAll(usedOrders);
//            orders.addAll(returnedOrders);
//            orders.addAll(completedOrders);
//        }else {
//            orders.removeAll(pushedOrders);
//        }
//        return orders;
//    }

    public void init() {
        new Thread(new OrderPushThread()).start();
    }

//    private Order copyOrder(Order orginalOrder){
//        Order order = new Order();
//        order.setPhone(orginalOrder.getPhone());
//        order.setCompleteTime(orginalOrder.getCompleteTime());
//        order.setRetTime(orginalOrder.getRetTime());
//        order.setGetTime(orginalOrder.getGetTime());
//        order.setStatus(orginalOrder.getStatus());
//        order.setStatusName(orginalOrder.getStatusName());
//        order.setCustomerName(orginalOrder.getCustomerName());
//        order.setVin(orginalOrder.getVin());
//        order.setCreateTime(orginalOrder.getCreateTime());
//        return order;
//    }
}
